package com.atguigu.tms.mock.task;


import com.atguigu.mock.util.RandomNum;
import com.atguigu.tms.mock.bean.*;
import com.atguigu.tms.mock.constant.TmsConstant;
import com.atguigu.tms.mock.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.atguigu.tms.mock.constant.TmsConstant.TASK_TYPE_COLLECT;
import static com.atguigu.tms.mock.constant.TmsConstant.TASK_TYPE_TRANSPORT;


@Component
@Slf4j
public class TransportMockTask {


    @Autowired
    TransportTaskService transportTaskService;

    @Autowired
    OrderOrgBoundService orderOrgBoundService;

    @Autowired
    TransportTaskProcessService transportTaskProcessService;

    @Autowired
    TransportTaskDetailService transportTaskDetailService;

    @Autowired
    TruckInfoService truckInfoService;

    @Autowired
    OrderInfoService orderInfoService;

    @Autowired
    ExpressTaskDeliveryService expressTaskDeliveryService;

    @Autowired
    OrderTraceLogService orderTraceLogService;

    @Autowired
    BaseOrganService baseOrganService;

    @Autowired
    LineBaseInfoService lineBaseInfoService;

  //  @Scheduled(cron = "0/15 * * * * ?")
    public void executeTask() {
        log.info("检查运输任务....");

    }


    // 检查所有sorted 的transport任务
    // 更新transport任务状态
    //  订单出站
    public void doTransportTaskStart(Date curDateTime, Integer curHour) {

        List<TransportTask> transportTaskList = transportTaskService.list(new QueryWrapper<TransportTask>().eq("status", TmsConstant.TRANSPORT_TASK_STATUS_SORTED));
        log.warn("启动运输任务:{}项",transportTaskList.size());
        for (TransportTask transportTask : transportTaskList) {
            Date sortedTime = transportTask.getUpdateTime()!=null?transportTask.getUpdateTime():transportTask.getCreateTime();
            sortedTime = DateUtils.addMinutes(sortedTime, RandomNum.getRandInt(1, 5));
            Date startDateTime = curDateTime.after(sortedTime) ? curDateTime : sortedTime;
            transportTask.setActualStartTime(startDateTime);
            transportTask.setUpdateTime(startDateTime);
            transportTask.setStatus(TmsConstant.TRANSPORT_TASK_STATUS_DRIVING);

            genTransportProcess(  transportTask);

            //处理运输任务的订单
            List<TransportTaskDetail> transportTaskDetailList = transportTaskDetailService.getTransportTaskDetailList(transportTask.getId());
            if(transportTaskDetailList==null||transportTaskDetailList.size()==0){
                continue;
            }

            List<Long> orderIdList= new ArrayList<>();
            for (TransportTaskDetail transportTaskDetail : transportTaskDetailList) {
                orderIdList.add(transportTaskDetail.getOrderId());
            }

            OrderOrgBound orderOrgBound = new OrderOrgBound();
            orderOrgBound.setStatus(TmsConstant.BOUND_STATUS_OUT);
            orderOrgBound.setOutboundTime(startDateTime);
            orderOrgBound.setOutboundEmpId(transportTask.getDriver1EmpId());
            orderOrgBound.setUpdateTime(startDateTime);
            orderOrgBoundService.update(orderOrgBound, new UpdateWrapper<OrderOrgBound>()
                    .in("order_id",orderIdList)
                    .eq("org_id",transportTask.getStartOrgId())
                    .isNull("outbound_time"));

            //更改订单状态和日志记录
            genOrderTraceLogTransportOut(  transportTask);


        }
        transportTaskService.saveOrUpdateBatch(transportTaskList, 100, true);


        //启动时需要初始化进度表！！！！！！！！！！！！！！！！！！！！！
        //!!!!

    }

    private  void genTransportProcess(TransportTask transportTask){
        TransportTaskProcess transportTaskProcess = new TransportTaskProcess();
        transportTaskProcess.setTransportTaskId(transportTask.getId());
        transportTaskProcess.setCreateTime(transportTask.getUpdateTime());
        transportTaskProcess.setIsDeleted("0");
        transportTaskProcess.setCurDistance(BigDecimal.ZERO);
        LineBaseInfo lineBaseInfo = lineBaseInfoService.getById(transportTask.getLineId(),true);
        transportTaskProcess.setLineDistance(lineBaseInfo.getDistance());
        transportTaskProcessService.saveOrUpdate(transportTaskProcess,true);
    }


    //检查所有的正在行驶的任务
    // 按照行驶 速度* 时间间隔 更新行驶进度。
    // 如果行驶 行驶进度达到
    public void doDrive(Date curDateTime, Integer curHour, Integer curMinute, Integer intervalMinute) {
        List<TransportTask> transportTaskList = transportTaskService.list(new QueryWrapper<TransportTask>().eq("status", TmsConstant.TRANSPORT_TASK_STATUS_DRIVING));
        List<TransportTaskProcess> updateTransportTaskProcessList=new ArrayList<>();
        for (TransportTask transportTask : transportTaskList) {
            if (transportTask.getActualStartTime().after(curDateTime)) { //未启动跳过
                continue;
            }
            TransportTaskProcess transportTaskProcess = transportTaskProcessService.getById(transportTask.getId(), true);

            BigDecimal curDistance = transportTaskProcess.getCurDistance();
            Long truckId = transportTask.getTruckId();
            TruckInfo truckInfo = truckInfoService.getById(truckId, true);
            Long speed = 0L;
            if (truckInfo.getTruckModelId() == 1) {
                speed = RandomNum.getRandLong(60, 80);
            } else {
                speed = RandomNum.getRandLong(30, 90);
            }
            BigDecimal moveDistance = ((BigDecimal.valueOf(speed).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP)).multiply(BigDecimal.valueOf(intervalMinute)));
            transportTaskProcess.setCurDistance(curDistance.add(moveDistance));
            transportTaskProcess.setUpdateTime(curDateTime);

            updateTransportTaskProcessList.add(transportTaskProcess);

            checkIfEnd(curDateTime, transportTask, transportTaskProcess);
        }
        transportTaskProcessService.saveOrUpdateBatch(updateTransportTaskProcessList, 10000,true);
    }


    // 更新订单状态和入站
    private void checkIfEnd(Date curDate, TransportTask transportTask, TransportTaskProcess transportTaskProcess) {

        if (transportTaskProcess.getCurDistance().compareTo(transportTaskProcess.getLineDistance())>=0 ) {
            transportTask.setStatus(TmsConstant.TRANSPORT_TASK_STATUS_FINISHED);
            transportTask.setActualDistance(transportTaskProcess.getCurDistance().longValue());
            transportTask.setActualEndTime(curDate);
            transportTask.setUpdateTime(curDate);

            transportTaskService.saveOrUpdate(transportTask, true);

            List<TransportTaskDetail> transportTaskDetailList =
                    transportTaskDetailService.list(new QueryWrapper<TransportTaskDetail>().eq("transport_task_id", transportTask.getId()));
            transportTask.setTransportTaskDetailList(transportTaskDetailList);

            //入站
            List<OrderOrgBound> orderOrgBoundList = orderOrgBoundService.initOrderOrgBoundList(transportTask);

            genOrderTraceLogTransportIn(  transportTask);
            //检查是否到达最终目的地
            checkIfFinalEnd(  transportTask,   orderOrgBoundList);



        }


    }


    private void checkIfFinalEnd(TransportTask transportTask, List<OrderOrgBound> orderOrgBoundList) {
        List<OrderOrgBound> orgBoundFinalEndList = new ArrayList<>();
        for (OrderOrgBound orderOrgBound : orderOrgBoundList) {
            Long orderId = orderOrgBound.getOrderId();
            OrderInfo orderInfo = orderInfoService.getById(orderId, true);
            BaseOrgan baseOrgan = baseOrganService.getById(transportTask.getEndOrgId(), true);
            if (orderInfo.getReceiverDistrictId().equals( baseOrgan.getRegionId())) {
                //到站 //生成派送任务
                orderOrgBound.setStatus(TmsConstant.BOUND_STATUS_DELIVERY_TASKED);
                orderOrgBound.setUpdateTime(transportTask.getActualEndTime());
                orgBoundFinalEndList.add(orderOrgBound);

            }
            orderOrgBoundService.saveOrUpdateBatch(orgBoundFinalEndList, 1000, true);


        }
        expressTaskDeliveryService.initExpressTaskDelivery(transportTask.getUpdateTime(), orgBoundFinalEndList);
    }

    private void genOrderTraceLogTransportOut(TransportTask transportTask) {


        if(transportTask.getOrderNum().equals(0)){
            return;
        }
        List<TransportTaskDetail> transportTaskDetailList= transportTaskDetailService.getTransportTaskDetailList(transportTask.getId());

        for (TransportTaskDetail transportTaskDetail : transportTaskDetailList) {

            OrderInfo orderInfo = orderInfoService.getById(transportTaskDetail.getOrderId(),true);
            OrderTraceLog orderTraceLog = new OrderTraceLog();
            orderTraceLog.setOrderId(orderInfo.getId());

            orderTraceLog.setTraceDesc("已出发，开往 " + transportTask.getEndOrgName());
            orderTraceLog.setCreateTime(transportTask.getUpdateTime());
            orderTraceLog.setCurTaskId(transportTask.getId());
            orderTraceLog.setChargeEmpId(transportTask.getDriver1EmpId());
            orderTraceLog.setTaskType(TASK_TYPE_TRANSPORT);
            orderTraceLog.setIsDeleted("0");
            orderTraceLogService.saveOrUpdate(orderTraceLog,true);

            if(orderInfo.getStatus().equals(TmsConstant.ORDER_STATUS_PENDING)){
                orderInfo.setStatus(TmsConstant.ORDER_STATUS_TRANSPORTING);
                orderInfo.setUpdateTime(transportTask.getUpdateTime());
                orderInfoService.saveOrUpdate(orderInfo,true);
            }

        }
    }

    private void genOrderTraceLogTransportIn(TransportTask transportTask) {
        if(transportTask.getOrderNum().equals(0)){
            return;
        }
        List<TransportTaskDetail> transportTaskDetailList= transportTaskDetailService.getTransportTaskDetailList(transportTask.getId());
        for (TransportTaskDetail transportTaskDetail : transportTaskDetailList) {

            OrderInfo orderInfo = orderInfoService.getById(transportTaskDetail.getOrderId(),true);
            OrderTraceLog orderTraceLog = new OrderTraceLog();
            orderTraceLog.setOrderId(orderInfo.getId());

            orderTraceLog.setTraceDesc("已到达 " + transportTask.getEndOrgName());
            orderTraceLog.setCreateTime(transportTask.getUpdateTime());
            orderTraceLog.setCurTaskId(transportTask.getId());
            orderTraceLog.setChargeEmpId(transportTask.getDriver1EmpId());
            orderTraceLog.setTaskType(TASK_TYPE_TRANSPORT);
            orderTraceLog.setIsDeleted("0");
            orderTraceLogService.saveOrUpdate(orderTraceLog);


        }

    }




    public static void main(String[] args) {
        Integer intervalMinute = 5;
        Long speed = RandomNum.getRandLong(60, 80);
        BigDecimal moveDistance = ((BigDecimal.valueOf(speed).divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP)).multiply(BigDecimal.valueOf(intervalMinute)));

        System.out.println(moveDistance);
    }
}
